package adminUser

import (
	"fmt"
	"net/http"
	"server/dao"
	"server/models"
	serviceUser "server/service/user"
	"server/utils"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

// @Tags 用户
// @Summary 获取用户列表
// @Description 可按用户姓名、手机号、角色查询，支持分页
// @Param   name     query    string     false        "用户姓名"
// @Param   phone     query    string     false        "手机号"
// @Param   page     query    int     false        "当前页码"
// @Param   per_page      query    int     false        "每页条目"
// @Success 200 {object} models.AdminUser
// @Router /api/admin/user [get]
func Get(c *gin.Context) {
	page, _ := strconv.ParseInt(c.Query("page"), 10, 32)
	perPage, _ := strconv.ParseInt(c.Query("per_page"), 10, 32)
	name := c.Query("name")
	phone := c.Query("phone")
	role_id := c.Query("role_id")

	res, errRes := serviceUser.GetUserList(page, perPage, name, phone, role_id)
	if errRes != nil {
		c.AbortWithError(500, errRes)
		return
	}

	// 正常返回数据
	c.JSON(
		200,
		utils.DealResponse(utils.Response{
			"data": gin.H{
				"list": res.List,
				"page": gin.H{
					"page":     page,
					"per_page": perPage,
					"total":    res.Count,
				},
			},
		}),
	)

}

// @Tags 用户
// @Summary 新建用户
// @Router /api/admin/user [post]
// @Param name query string true "用户姓名"
// @Param phone query string true "手机号"
// @Param status query string true "状态"
// @Param Roles query array false "角色id"
// @Success 200 {object} models.AdminUser
func Create(c *gin.Context) {
	var postData struct {
		Name   string   `json:"name"`
		Phone  string   `json:"phone"`
		Status int8     `json:"status"`
		Roles  []uint32 `json:"Roles"`
	}
	c.BindJSON(&postData)

	var doc models.AdminUser
	doc.Name = postData.Name
	doc.Phone = postData.Phone
	doc.Status = postData.Status
	doc.CreatedTime = uint64(time.Now().Unix())
	doc.UpdatedTime = uint64(time.Now().Unix())
	err := dao.DB.Create(&doc).Error
	if err != nil {
		c.AbortWithError(500, err)
		return
	}

	var Roles []models.AdminRole
	for _, roleID := range postData.Roles {
		Roles = append(Roles, models.AdminRole{
			ID: roleID,
		})
	}
	fmt.Printf("%#v\n", Roles)
	// 替换关联
	errAssociation := dao.DB.Model(&doc).Association("AdminRoles").Replace(&Roles).Error
	if errAssociation != nil {
		c.AbortWithError(500, errAssociation)
		return
	}

	c.JSON(
		200,
		utils.DealResponse(utils.Response{
			"data": doc,
		}),
	)
}

func Update(c *gin.Context) {
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
		return
	}
	var postData struct {
		Name   string   `json:"name"`
		Phone  string   `json:"phone"`
		Status int8     `json:"status"`
		Roles  []uint32 `json:"Roles"`
	}
	c.BindJSON(&postData)
	numId, _ := strconv.ParseUint(id, 10, 64)
	updateDoc := models.AdminUser{
		ID:          uint32(numId),
		Name:        postData.Name,
		Phone:       postData.Phone,
		Status:      postData.Status,
		UpdatedTime: uint64(time.Now().Unix()),
	}
	err := dao.DB.Model(&models.AdminUser{}).Where("id=?", id).Updates(&updateDoc).Error
	if err != nil {
		c.AbortWithError(500, err)
		return
	}

	var Roles []models.AdminRole
	for _, roleID := range postData.Roles {
		Roles = append(Roles, models.AdminRole{
			ID: roleID,
		})
	}
	fmt.Printf("%#v\n", Roles)
	// 替换关联
	errAssociation := dao.DB.Model(&updateDoc).Association("AdminRoles").Replace(&Roles).Error
	if errAssociation != nil {
		c.AbortWithError(500, errAssociation)
		return
	}

	c.JSON(
		200,
		utils.DealResponse(utils.Response{
			"data": updateDoc,
		}),
	)
}

func Delete(c *gin.Context) {
	id, ok := c.Params.Get("id")
	if !ok {
		c.JSON(http.StatusOK, gin.H{"error": "无效的id"})
		return
	}
	err := dao.DB.Model(&models.AdminUser{}).Where("id=?", id).Updates(map[string]interface{}{
		"Status": -1,
	}).Error
	if err != nil {
		c.AbortWithError(500, err)
		return
	}
	c.JSON(
		200,
		utils.DealResponse(utils.Response{
			"data": "ok",
		}),
	)
}

func Login(c *gin.Context) {
	var postData struct {
		Phone      string `json:"phone"`
		Password   string `json:"password"`
		Verificode string `json:"verifi_code"`
	}
	c.BindJSON(&postData)

	var resDoc models.AdminUser
	dao.DB.Model(&models.AdminUser{}).Select([]string{"phone", "password"}).Where("phone = ?", postData.Phone).Preload("AdminRoles").Find(&resDoc)

	if resDoc.Password != postData.Password {
		c.JSON(
			200,
			utils.DealResponse(utils.Response{
				"code": 5000,
				"msg":  "账号密码不匹配",
			}),
		)
		return
	}

	// codeRes, rdbErr := dao.RdbGet("verificode:" + postData.Phone)
	// if rdbErr != nil {
	// 	c.AbortWithError(500, rdbErr)
	// 	return
	// }
	// if codeRes != postData.Verificode {
	// 	c.JSON(
	// 		200,
	// 		utils.DealResponse(utils.Response{
	// 			"code": 5000,
	// 			"msg":  "该验证码无效",
	// 		}),
	// 	)
	// 	return
	// }

	token, errToken := utils.GenToken(resDoc.Phone)
	if errToken != nil {
		c.AbortWithError(500, errToken)
		return
	}
	c.JSON(
		200,
		utils.DealResponse(utils.Response{
			"data": token,
		}),
	)
}

func UserInfo(c *gin.Context) {
	// phone := c.Query("phone")
	phone, _ := c.Get("phone")
	var resDoc struct {
		models.AdminUser
		Auths []models.AdminAuth `json:"auths"`
	}
	errFind := dao.DB.Model(&models.AdminUser{}).Where("phone = ?", phone).Preload("AdminRoles").Preload("AdminRoles.AdminAuths").Find(&resDoc).Error
	if errFind != nil {
		c.AbortWithError(500, errFind)
		return
	}
	var userAuths []models.AdminAuth
	for _, roles := range resDoc.AdminRoles {
		for _, auth1 := range roles.AdminAuths {
			flag := false
			for _, auth2 := range userAuths {
				if auth1.ID == auth2.ID {
					flag = true
				}
			}
			if !flag {
				userAuths = append(userAuths, auth1)
			}
		}
	}
	resDoc.Auths = userAuths
	c.JSON(
		200,
		utils.DealResponse(utils.Response{
			"data": resDoc,
		}),
	)
}

func ChangePassword(c *gin.Context) {
	var postData struct {
		ID          uint32 `json:"id"`
		Password    string `json:"password"`
		Newpassword string `json:"newpassword"`
	}
	c.BindJSON(&postData)

	var resDoc models.AdminUser
	dao.DB.Model(&models.AdminUser{}).Select([]string{"phone", "password"}).Where("id = ?", postData.ID).Preload("AdminRoles").Find(&resDoc)
	if resDoc.Password != postData.Password {
		c.JSON(
			200,
			utils.DealResponse(utils.Response{
				"code": 500,
				"msg":  "旧密码不匹配",
			}),
		)
		return
	}

	updateDoc := models.AdminUser{
		ID:          postData.ID,
		Password:    postData.Newpassword,
		UpdatedTime: uint64(time.Now().Unix()),
	}
	err := dao.DB.Model(&models.AdminUser{}).Updates(&updateDoc).Error
	if err != nil {
		c.AbortWithError(500, err)
		return
	}

	c.JSON(
		200,
		utils.DealResponse(utils.Response{
			"data": "",
		}),
	)
}

func GetVerifiCode(c *gin.Context) {
	var postData struct {
		Phone string `json:"phone"`
	}
	c.BindJSON(&postData)
	code := utils.GenValidateCode(6)
	fmt.Printf("%#v\n", postData)
	fmt.Println(code)
	// 存放redis
	rdbErr := dao.RdbSet("verificode:"+postData.Phone, code, 5*time.Minute)
	if rdbErr != nil {
		c.AbortWithError(500, rdbErr)
		return
	}

	_, err := utils.PostVerifiSms(postData.Phone, code)
	if err != nil {
		c.AbortWithError(500, err)
		return
	}
	// 正常返回数据
	c.JSON(
		200,
		utils.DealResponse(utils.Response{
			"data": gin.H{
				"status": "ok",
			},
		}),
	)

}
